package com.authine.cloudpivot.ext.applicationservice.base;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.enums.CustomerOrderStatusEnum;
import com.authine.cloudpivot.ext.enums.OrderGoodsStatusV1Enum;
import com.authine.cloudpivot.ext.enums.commoditymaterials.DeliverNoticeEnum;
import com.authine.cloudpivot.ext.enums.commoditymaterials.MaterialNoticeEnum;
import com.authine.cloudpivot.ext.enums.order.*;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.common.json.JsonUtils;
import com.authine.hermes.app.launcher.org.Department;
import com.authine.hermes.app.launcher.org.User;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.common.TableHelper;
import com.authine.mvp.app.launcher.domain.AttachmentFormat;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.gateway.bo.BOValidatedAndFormatService;
import com.authine.mvp.app.launcher.utils.JsonParseObject;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class ApplicationBaseService extends ApplicationService {
    private final NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);
    private final TableHelper tableHelper = ApplicationContextUtils.getBean(TableHelper.class);
    private BOValidatedAndFormatService bOValidatedAndFormatService = ApplicationContextUtils.getBean(BOValidatedAndFormatService.class);

    /**
     * ----------------------------------------------------DB通用执行sql------start---------------------------------------------
     */

    /**
     * 获取某个表的数据通过主键id
     *
     * @param id
     * @param schemaCode
     * @return
     */
    public Map<String, Object> selectModelById(String id, String schemaCode) {
        return selectModelById(id, null, schemaCode);
    }

    /**
     * 获取某个表的数据通过主键id，可跨数据库
     *
     * @param id
     * @param appCode
     * @param schemaCode
     * @return
     */
    public Map<String, Object> selectModelById(String id, String appCode, String schemaCode) {
        String tableName = getTableName(appCode, schemaCode);
        log.info("------------------------通过多个参数查询" + tableName + "表 Param：{}------------------------", id);
        if (StringUtils.isBlank(id) || StringUtils.isBlank(tableName)) {
            return null;
        }
        StringBuilder listSql = new StringBuilder();
        listSql.append("select * from " + tableName + " where deleted = '0' and id ='" + id + "'");
        log.info("------------------------通过多个参数查询" + tableName + "表 SQL：{}------------------------", listSql);
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(result)) {
            return null;
        } else {
            return result.get(0);
        }
    }

    /**
     * 获取某个表的数据通过主键id，可跨数据库
     *
     * @param ids
     * @return
     */
    public List<Map<String, Object>> selectModelByIn(Map<String, List<String>> ids, String tableName) {
        log.info("------------------------通过多个参数查询" + tableName + "表 Param：{}------------------------", ids);
        if (CollectionUtils.isEmpty(ids) || StringUtils.isBlank(tableName)) {
            return null;
        }
        StringBuilder listSql = new StringBuilder();
        StringBuilder sql = new StringBuilder();
        for (String key : ids.keySet()) {
            String idInSql = ids.get(key).stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", "));
            listSql.append(" and " + key + " in (" + idInSql + ")");
        }

        sql.append("select * from " + tableName + " where deleted = '0' " + listSql);
        log.info("------------------------通过多个参数查询" + tableName + "表 SQL：{}------------------------", sql);
        List<Map<String, Object>> result = jdbcTemplate.queryForList(sql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(result)) {
            return null;
        } else {
            return result;
        }
    }

    /**
     * 获取某个表的数据通过多个参数，可跨数据库
     *
     * @param appCode
     * @param schemaCode
     * @return
     */
    public List<Map<String, Object>> selectModelByMaps(List<Map<String, Object>> paramList, String appCode, String schemaCode) {
        String tableName = getTableName(appCode, schemaCode);
        log.info("------------------------通过多个参数查询" + tableName + "表 Param：{}------------------------", paramList);
        if (CollectionUtils.isEmpty(paramList)) {
            return null;
        }
        String sql = "";
        for (Map<String, Object> map : paramList) {
            for (String key : map.keySet()) {
                sql += " and " + key + " ='" + map.get(key) + "'";
            }
        }
        StringBuilder listSql = new StringBuilder();
        listSql.append("select * from " + tableName + " where deleted = '0' " + sql);
        log.info("------------------------通过多个参数查询" + tableName + "表 SQL：{}------------------------", listSql);
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), new HashMap<>());
        return result;
    }

    /**
     * 获取某个表的数据通过参数，可多参数
     *
     * @return
     */
    public List<Map<String, Object>> selectModelByMaps(List<Map<String, Object>> paramList, String schemaCode) {
        return selectModelByMaps(paramList, null, schemaCode);
    }

    /**
     * 获取某个表的数据通过参数，可多参数
     *
     * @return
     */
    public List<Map<String, Object>> selectModelByMaps(Map<String, Object> paramMap, String appCode, String schemaCode) {
        return selectModelByMaps(Collections.singletonList(paramMap), appCode, schemaCode);
    }

    /**
     * 获取某个表的数据通过参数，可多参数
     *
     * @param schemaCode
     * @return
     */
    public List<Map<String, Object>> selectModelByMaps(Map<String, Object> paramMap, String schemaCode) {
        return selectModelByMaps(Collections.singletonList(paramMap), null, schemaCode);
    }

    /**
     * 获取当前登录人部门信息
     *
     * @return
     */
    public Map<String, Object> getCurrentDept() {
        StringBuilder listSql = new StringBuilder();
        listSql.append("select d.* from " + AppConst.APP_COMMONSERVICE + ".h_org_department d " +
                "inner JOIN " + AppConst.APP_COMMONSERVICE + ".h_org_dept_user du on d.id = du.deptId " +
                "inner join " + AppConst.APP_COMMONSERVICE + ".h_org_user u on u.id = du.userId " +
                "where u.userBaseId ='" + RequestContext.getLoginId() + "'");
        log.info("------------------------通过当前登录人用户id:{}查询用户所在部门 SQL：{}------------------------", RequestContext.getLoginId(), listSql);
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(result)) {
            return null;
        } else {
            return result.get(0);
        }
    }

    /**
     * 获取应用表名(可获取其他应用表名)
     *
     * @param appCode
     * @param schemaCode
     * @return
     */
    public String getTableName(String appCode, String schemaCode) {
        if (StringUtils.isBlank(appCode)) {
            return getTableName(schemaCode);
        }
        return String.format("%s.i_%s_%s", appCode.toLowerCase(), appCode.toLowerCase(), schemaCode.toLowerCase());
    }

    /**
     * 获取表名称
     *
     * @param schemaCode
     * @return
     */
    public String getTableName(String schemaCode) {
        return tableHelper.getTableName(schemaCode);
    }

    /**
     * 获取当前登录人角色
     */
    public List<Map<String, Object>> getCurrentUserRole() {
        String sql = "select d.* from " + AppConst.APP_COMMONSERVICE + ".h_org_role d " +
                "inner JOIN " + AppConst.APP_COMMONSERVICE + ".h_org_role_user du on d.id = du.roleId " +
                "inner join " + AppConst.APP_COMMONSERVICE + ".h_org_user u on u.id = du.unitId " +
                "where u.userBaseId = '" + RequestContext.getLoginId() + "'";
        List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, new HashMap<>());
        if (CollectionUtils.isEmpty(result)) {
            return null;
        } else {
            return result;
        }
    }

    /**
     * 通过userBaseId获取选人控件值
     *
     * @param id
     * @return
     */
    public SelectorFormat getSelectorFormat(String id, UnitType unitType) {
        if (StringUtils.isBlank(id)) {
            id = RequestContext.getCorpLoginId();
        }
        SelectorFormat senderSF = new SelectorFormat();
        User sender = this.orgService.getUserByUserId(id).getData();
        //部门
        if (unitType.getIndex() == 1) {
            senderSF.setId(sender.getDetailInfo().getDepartmentId());
            senderSF.setName(sender.getDetailInfo().getMainDepartmentName());
            senderSF.setType(unitType.getIndex());
        }
        //角色
        if (unitType.getIndex() == 2) {
            senderSF.setId(sender.getDetailInfo().getRoleIds().get(0));
            senderSF.setName(sender.getDetailInfo().getRoleName());
            senderSF.setType(unitType.getIndex());
        }
        //用户
        if (unitType.getIndex() == 3) {
            senderSF.setId(sender.getDetailInfo().getId());
            senderSF.setName(sender.getDetailInfo().getName());
            senderSF.setType(unitType.getIndex());
        }
        return senderSF;
    }

    /**
     * 通过userBaseId获取选人控件值
     *
     * @return
     */
    public SelectorFormat getSelectorFormat() {
        SelectorFormat senderSF = new SelectorFormat();
        senderSF.setId(RequestContext.getLoginId());
        senderSF.setName(RequestContext.getLoginRealName());
        senderSF.setType(3);
        return senderSF;
    }

    /**
     * 获取退货订单商品表通过订单商品id
     */
    public List<Map<String, Object>> getGoodsReturnsByOrderGoodsId(Collection<String> orderCustomerGoodsId, Collection<String> orderVendorGoodsId) {
        String orderGoodsReturnsDB = getTableName(ModelConst.T_ORDER_GOODS_RETURNS);
        if (CollectionUtils.isEmpty(orderCustomerGoodsId) && CollectionUtils.isEmpty(orderVendorGoodsId)) {
            return null;
        }
        StringBuilder orderGoodsReturnsSql = new StringBuilder();
        orderGoodsReturnsSql.append("select * from " + orderGoodsReturnsDB + " where deleted = '0' ");
        if (!CollectionUtils.isEmpty(orderCustomerGoodsId)) {
            String orderCustomerGoodsIdInSql = " and order_customer_goods_id in (" + orderCustomerGoodsId.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", ")) + ")";
            orderGoodsReturnsSql.append(orderCustomerGoodsIdInSql);
        }
        if (!CollectionUtils.isEmpty(orderVendorGoodsId)) {
            String orderVendorGoodsIdIdInSql = " and order_vendor_goods_id in (" + orderVendorGoodsId.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", ")) + ")";
            orderGoodsReturnsSql.append(orderVendorGoodsIdIdInSql);
        }
        return jdbcTemplate.queryForList(orderGoodsReturnsSql.toString(), new HashMap<>());
    }

    /**
     * 获取供应商订单商品表通过订单商品id
     */
    public List<Map<String, Object>> getOrderVendorGoodsByGoodsId(Collection<String> orderGoodsId, Collection<String> vendorOrgIds) {
        if (CollectionUtils.isEmpty(orderGoodsId)) {
            return null;
        }
        StringBuilder orderVendorGoodsSql = new StringBuilder();
        if (!CollectionUtils.isEmpty(vendorOrgIds)) {
            String orderVendorGoodsIdIdInSql = " and vendor_organization_id in (" + vendorOrgIds.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", ")) + ")";
            orderVendorGoodsSql.append(orderVendorGoodsIdIdInSql);
        }
        String orderVendorGoodsDB = getTableName(ModelConst.T_ORDER_VENDOR_GOODS);
        String orderVendorGoodsIdInSql = orderGoodsId.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", "));
        String sql = "select * from " + orderVendorGoodsDB + " where deleted = '0' and id in (" + orderVendorGoodsIdInSql + ")";
        List<Map<String, Object>> orderVendorGoodsList = jdbcTemplate.queryForList(sql, new HashMap<>());
        return orderVendorGoodsList;
    }

    /**
     * 获取客户订单商品表通过订单商品id
     */
    public List<Map<String, Object>> getOrderCustomerGoodsByGoodsId(Collection<String> orderGoodsId) {
        if (CollectionUtils.isEmpty(orderGoodsId)) {
            return null;
        }
        String orderCustomerGoodsDB = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
        String orderCustomerGoodsIdInSql = orderGoodsId.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", "));
        String sql = "select * from " + orderCustomerGoodsDB + " where deleted = '0' and id in (" + orderCustomerGoodsIdInSql + ")";
        List<Map<String, Object>> orderCustomerGoodsList = jdbcTemplate.queryForList(sql, new HashMap<>());
        return orderCustomerGoodsList;
    }

    /**
     * 获取订单商品收货表通过客户订单商品id或供应商订单商品id
     */
    public List<Map<String, Object>> getOrderGoodsAcceptByGoodsId(Collection<String> orderCustomerGoodsId, Collection<String> orderVendorGoodsId) {
        if (CollectionUtils.isEmpty(orderCustomerGoodsId) && CollectionUtils.isEmpty(orderVendorGoodsId)) {
            return null;
        }
        String orderGoodsAcceptDB = getTableName(ModelConst.T_ORDER_GOODS_ACCEPT);
        StringBuilder orderGoodsAcceptSql = new StringBuilder();
        orderGoodsAcceptSql.append("select * from " + orderGoodsAcceptDB + " where deleted = '0' ");
        if (!CollectionUtils.isEmpty(orderCustomerGoodsId)) {
            String orderCustomerGoodsIdInSql = " and order_customer_goods_id in (" + orderCustomerGoodsId.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", ")) + ")";
            orderGoodsAcceptSql.append(orderCustomerGoodsIdInSql);
        }
        if (!CollectionUtils.isEmpty(orderVendorGoodsId)) {
            String orderVendorGoodsIdIdInSql = " and order_vendor_goods_id in (" + orderVendorGoodsId.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", ")) + ")";
            orderGoodsAcceptSql.append(orderVendorGoodsIdIdInSql);
        }
        return jdbcTemplate.queryForList(orderGoodsAcceptSql.toString(), new HashMap<>());
    }

    /**
     * 获取订单商品收货表通过客户订单商品id或供应商订单商品id
     */
    public List<Map<String, Object>> getOrderGoodsTraceByGoodsId(String orderCustomerGoodsId, String orderVendorGoodsId) {
        if (StringUtils.isBlank(orderCustomerGoodsId) && StringUtils.isBlank(orderVendorGoodsId)) {
            return null;
        }
        String orderTraceDB = getTableName(ModelConst.T_ORDER_TRACE);
        StringBuilder orderTraceSql = new StringBuilder();
        orderTraceSql.append("select * from " + orderTraceDB + " where deleted = '0' ");
        if (!StringUtils.isBlank(orderCustomerGoodsId)) {
            String orderCustomerGoodsIdInSql = " and order_customer_goods_id = '" + orderCustomerGoodsId + "'";
            orderTraceSql.append(orderCustomerGoodsIdInSql);
        }
        if (!StringUtils.isBlank(orderVendorGoodsId)) {
            String orderVendorGoodsIdIdInSql = " and order_vendor_goods_id = '" + orderVendorGoodsId + "'";
            orderTraceSql.append(orderVendorGoodsIdIdInSql);
        }
        return jdbcTemplate.queryForList(orderTraceSql.toString(), new HashMap<>());
    }

    /**
     * 获取个人中心地址
     */
    public List<Map<String, Object>> getAddress(String memberId, boolean defaultOnly, String id) {
        String tableName = getTableName(AppConst.PERSONAL_CENTER, ModelConst.T_MEMBER_DELIVER_ADDRESS);
        StringBuilder sql = new StringBuilder();
        sql.append("select * from " + tableName + " where deleted ='0'");
        if (null != memberId) {
            sql.append(" and member_id->'$.id' = '" + memberId + "'");
        } else {
            sql.append(" and member_id->'$.id' = '" + RequestContext.getCorpLoginId() + "'");
        }
        if (defaultOnly) {
            sql.append(" and default_address = '1'");
        }
        if (StringUtils.isNotBlank(id)) {
            sql.append(" and id = '" + id + "'");
        }
        log.info("------------------------查询 SQL：{}------------------------", sql);
        List<Map<String, Object>> result = jdbcTemplate.queryForList(sql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(result)) {
            return null;
        } else {
            return result;
        }
    }

    /**
     * 获取个人会员银行信息表
     */
    public List<Map<String, Object>> getBankAccount(String memberId, boolean defaultOnly, String id) {
        String tableName = getTableName(AppConst.PERSONAL_CENTER, ModelConst.T_MEMBER_BANK_ACCOUNT);
        StringBuilder sql = new StringBuilder();
        sql.append("select * from " + tableName + " where deleted ='0'");
        if (null != memberId) {
            sql.append(" and member_id->'$.id' = '" + memberId + "'");
        } else {
            sql.append(" and member_id->'$.id' = '" + RequestContext.getCorpLoginId() + "'");
        }
        if (defaultOnly) {
            sql.append(" and default_bank_account = '1'");
        }
        if (StringUtils.isNotBlank(id)) {
            sql.append(" and id = '" + id + "'");
        }
        log.info("------------------------查询 SQL：{}------------------------", sql);
        List<Map<String, Object>> result = jdbcTemplate.queryForList(sql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(result)) {
            return null;
        } else {
            return result;
        }
    }

    /**
     * 获库存使用单据相关物料表通过id集合
     */
    public List<Map<String, Object>> getStockBillMaterialByIds(Collection<String> stockBillMaterialIds) {
        if (CollectionUtils.isEmpty(stockBillMaterialIds)) {
            return null;
        }
        String stockBillMaterialDB = getTableName(ModelConst.T_STOCK_BILL_MATERIAL);
        String stockBillMaterialInSql = stockBillMaterialIds.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", "));
        String sql = "select * from " + stockBillMaterialDB + " where deleted = '0' and id in (" + stockBillMaterialInSql + ")";
        List<Map<String, Object>> stockBillMaterialList = jdbcTemplate.queryForList(sql, new HashMap<>());
        return stockBillMaterialList;
    }

    /**
     * @param goodsId
     * @return
     */
    public Map<String, Object> getInquiryGoodsByGoodsId(String goodsId) {
        if (StringUtils.isBlank(goodsId)) {
            return null;
        }
        //最大库存量
        StringBuilder listSql = new StringBuilder();
        String goodsPurchaseTableName = getTableName(AppConst.COMMODITYMATERIALS, ModelConst.T_GOODS_PURCHASE);
        String quotationGoodsTableName = getTableName(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS);
        String inquiryGoodsTableName = getTableName(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY_GOODS);
        listSql.append("select ig.* from " + goodsPurchaseTableName + " pg\n" +
                " inner join " + quotationGoodsTableName + " qg on pg.quotation_goods_id = qg.id\n" +
                " inner join " + inquiryGoodsTableName + " ig on qg.inquiry_goods_id = ig.id\n" +
                " where pg.id = '" + goodsId + "' and pg.deleted = '0' and qg.deleted ='0' and ig.deleted ='0'");
        List<Map<String, Object>> results = jdbcTemplate.queryForList(listSql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(results)) {
            return null;
        } else {
            return results.get(0);
        }
    }

    /**
     * @param goodsId
     * @return
     */
    public Map<String, Object> getQuotationGoodsByGoodsId(String goodsId) {
        if (StringUtils.isBlank(goodsId)) {
            return null;
        }
        //最大库存量
        StringBuilder listSql = new StringBuilder();
        String goodsPurchaseTableName = getTableName(AppConst.COMMODITYMATERIALS, ModelConst.T_GOODS_PURCHASE);
        String quotationGoodsTableName = getTableName(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS);
        listSql.append("select qg.* from " + goodsPurchaseTableName + " pg\n" +
                " inner join " + quotationGoodsTableName + " qg on pg.quotation_goods_id = qg.id\n" +
                " where pg.id = '" + goodsId + "' and pg.deleted = '0' and qg.deleted ='0' ");
        List<Map<String, Object>> results = jdbcTemplate.queryForList(listSql.toString(), new HashMap<>());
        if (CollectionUtils.isEmpty(results)) {
            return null;
        } else {
            return results.get(0);
        }
    }

    /**
     * 获取数据字典
     *
     * @param code
     * @param type
     * @return
     */
    /*public List<Map<String, Object>> getDictionaryItem(String code, DictionaryType type, String itemCode) {
        //默认查询简单键值结构
        if (null == type) {
            type = DictionaryType.KEYVALUE;
        }
        StringBuilder sql = new StringBuilder();
        sql.append("select di.* from " + AppConst.APP_METADATA + "." + ModelConst.DICTIONARY + " d " +
                " inner join " + AppConst.APP_METADATA + "." + ModelConst.DICTIONARY_ITEM + " di on d.id = di.dict_id " +
                " where d.type='" + type.getCode() + "' and d.deleted='0' and di.deleted='0'");
        if (StringUtils.isNotBlank(code)) {
            sql.append(" and d.code = '" + code + "'");
        }
        if (StringUtils.isNotBlank(itemCode)) {
            sql.append(" and di.code = '" + itemCode + "'");
        }
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql.toString(), new HashMap<>());
        return resultList;
    }
*/
    /**----------------------------------------------------DB通用执行sql------end---------------------------------------------*/


    /**
     * ----------------------------------------------------订单数量次数相关计算------start---------------------------------------------
     */
    //已发次数
    public Integer getDeliverCount(String orderCustomerGoodsId, String orderVendorGoodsId) {
        List<Map<String, Object>> orderGoodsTraceGoodsId = getOrderGoodsTraceByGoodsId(orderCustomerGoodsId, orderVendorGoodsId);
        return null != orderGoodsTraceGoodsId && !orderGoodsTraceGoodsId.isEmpty() ? orderGoodsTraceGoodsId.size() : 0;
    }

    //已发数量
    public BigDecimal getDeliveredNum(String orderCustomerGoodsId, String orderVendorGoodsId) {
        List<Map<String, Object>> transportByOrderGoodsId = getOrderGoodsTraceByGoodsId(orderCustomerGoodsId, orderVendorGoodsId);
        BigDecimal deliveredNum = BigDecimal.ZERO;
        for (Map<String, Object> item : transportByOrderGoodsId) {
            if (null != item.get("quantity") && item.get("type").equals(TraceTypeEnum.ShippingLogistics))
                deliveredNum = BigDecimalUtils.add(deliveredNum, BigDecimalUtils.isNull(item.get("quantity")));
        }
        return deliveredNum;
    }

    //已收次数
    public Integer getReceiveCount(String orderCustomerGoodsId, String orderVendorGoodsId) {
        List<Map<String, Object>> receivedByOrderGoodsId = getOrderGoodsAcceptByGoodsId(Collections.singletonList(orderCustomerGoodsId), Collections.singletonList(orderVendorGoodsId));
        return null != receivedByOrderGoodsId && !receivedByOrderGoodsId.isEmpty() ? receivedByOrderGoodsId.size() : 0;
    }

    //已收数量
    public BigDecimal getReceivedNum(String orderCustomerGoodsId, String orderVendorGoodsId) {
        List<Map<String, Object>> receivedByOrderGoodsId = getOrderGoodsAcceptByGoodsId(Collections.singletonList(orderCustomerGoodsId), Collections.singletonList(orderVendorGoodsId));
        BigDecimal recevicedNum = BigDecimal.ZERO;
        for (Map<String, Object> item : receivedByOrderGoodsId) {
            if (null != item.get("quantity_received"))
                recevicedNum = BigDecimalUtils.add(recevicedNum, BigDecimalUtils.isNull(item.get("quantity_received")));
        }
        return recevicedNum;
    }

    //已退次数
    public Integer getRefundCount(String orderCustomerGoodsId, String orderVendorGoodsId) {
        Collection<String> orderCustomerGoodsIds = StringUtils.isBlank(orderCustomerGoodsId) ? null : Collections.singleton(orderCustomerGoodsId);
        Collection<String> orderVendorGoodsIds = StringUtils.isBlank(orderVendorGoodsId) ? null : Collections.singleton(orderVendorGoodsId);
        List<Map<String, Object>> refundByOrderGoodsId = getGoodsReturnsByOrderGoodsId(orderCustomerGoodsIds, orderVendorGoodsIds);
        return null != refundByOrderGoodsId && !refundByOrderGoodsId.isEmpty() ? refundByOrderGoodsId.size() : 0;
    }

    //已退数量
    public BigDecimal getRefundedNum(String orderCustomerGoodsId, String orderVendorGoodsId) {
        Collection<String> orderCustomerGoodsIds = StringUtils.isBlank(orderCustomerGoodsId) ? null : Collections.singleton(orderCustomerGoodsId);
        Collection<String> orderVendorGoodsIds = StringUtils.isBlank(orderVendorGoodsId) ? null : Collections.singleton(orderVendorGoodsId);
        List<Map<String, Object>> refundByOrderGoodsId = getGoodsReturnsByOrderGoodsId(orderCustomerGoodsIds, orderVendorGoodsIds);
        BigDecimal refundedNum = BigDecimal.ZERO;
        for (Map<String, Object> item : refundByOrderGoodsId) {
            if (null != item.get("quantity")&&null!= item.get("order_goods_returns_status")&&OrderGoodsReturnsStatusEnum.getNormalStatus().contains(item.get("order_goods_returns_status")))
                refundedNum = BigDecimalUtils.add(refundedNum, BigDecimalUtils.isNull(item.get("quantity")));
        }
        return refundedNum;
    }


    //可收数量（已发数量-已收数量-已退货数量+退的收货的数量）
    @Deprecated
    public BigDecimal getEnableNum(String orderCustomerGoodsId, String orderVendorGoodsId, BigDecimal returnedNum, BigDecimal returnReceivedNum) {
        if (null == orderCustomerGoodsId && null == orderVendorGoodsId) return BigDecimal.ZERO;
        return BigDecimalUtils.add(BigDecimalUtils.sub(BigDecimalUtils.sub(getDeliveredNum(orderCustomerGoodsId, orderVendorGoodsId),
                getReceivedNum(orderCustomerGoodsId, orderVendorGoodsId)), returnedNum), returnReceivedNum);
    }

    //可收数量 = 订单总数（t_order_customer_goods.quantity）-退未发数量（t_order_customer_goods.quantity_return_not_shipped）-已收数量（t_order_customer_goods.quantity_received）
    public BigDecimal getEnableNum(String orderCustomerGoodsId) {
        if (StringUtils.isBlank(orderCustomerGoodsId)) {
            return BigDecimal.ZERO;
        }
        Map<String, Object> orderCustomerGoods = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .selectField("(quantity-ifnull(quantity_return_not_shipped, 0.0)-ifnull(quantity_received, 0.0)) as enable_num").eq("id", orderCustomerGoodsId).queryForMap();
        return CollectionUtils.isEmpty(orderCustomerGoods)?BigDecimal.ZERO:BigDecimalUtils.isNull(orderCustomerGoods.get("enable_num"));
    }

    //可退数量（总数量-已退数量）
    public BigDecimal getRefundableNum(String orderCustomerGoodsId, String orderVendorGoodsId, BigDecimal num) {
        if (null == orderCustomerGoodsId && null == orderVendorGoodsId) return BigDecimal.ZERO;
        return BigDecimalUtils.sub(num, getRefundedNum(orderCustomerGoodsId, orderVendorGoodsId));
    }

    //可退数量：订单总数（t_order_customer_goods.quantity）-退未发货数量（t_order_customer_goods.quantity_return_not_shipped）-退已发货数量（t_order_customer_goods.quantity_return_shipped）
    public BigDecimal getRefundableNum(String orderCustomerGoodsId) {
        Map<String, Object> orderCustomerGoods = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .selectField("(quantity-ifnull(quantity_return_not_shipped, 0.0)-ifnull(quantity_return_shipped, 0.0)) as refundable_num")
                .eq("id", orderCustomerGoodsId).queryForMap();
        return CollectionUtils.isEmpty(orderCustomerGoods)?BigDecimal.ZERO:BigDecimalUtils.isNull(orderCustomerGoods.get("refundable_num"));
    }

    //可发数量（可退数量-已发数量+已退货数量）
    @Deprecated
    public BigDecimal getDeliverableNum(String orderCustomerGoodsId, String orderVendorGoodsId, BigDecimal returnedNum, BigDecimal num) {
        if (null == orderCustomerGoodsId && null == orderVendorGoodsId) return BigDecimal.ZERO;
        return BigDecimalUtils.add(BigDecimalUtils.sub(getRefundableNum(orderCustomerGoodsId, orderVendorGoodsId, num),
                getDeliveredNum(orderCustomerGoodsId, orderVendorGoodsId)), returnedNum);
    }

    //可发数量 = 订单总数（t_order_vendor_goods.quantity）-退未发货数量（t_order_vendor_goods.quantity_return_not_shipped）-已发货数量（t_order_vendor_goods.quantity_shipped）
    public BigDecimal getDeliverableNum(String orderVendorGoodsId) {
        if (StringUtils.isBlank(orderVendorGoodsId)) {
            return BigDecimal.ZERO;
        }
        Map<String, Object> orderCustomerGoods = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS)
                .selectField("(quantity-ifnull(quantity_return_not_shipped, 0.0)-ifnull(quantity_shipped, 0.0)) as deliverable_num")
                .eq("id", orderVendorGoodsId).queryForMap();
        return CollectionUtils.isEmpty(orderCustomerGoods)?BigDecimal.ZERO:BigDecimalUtils.isNull(orderCustomerGoods.get("deliverable_num"));
    }

    //未发货数量=总数量-已退的-已发货数量+仅退货数量
    public BigDecimal getUndeliveredNum(String orderCustomerGoodsId) {
        if (StringUtils.isBlank(orderCustomerGoodsId)) {
            return BigDecimal.ZERO;
        }
        Map<String, Object> orderCustomerGoods = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .selectField("(quantity-ifnull(quantity_return_not_shipped, 0.0)-ifnull(quantity_return_shipped, 0.0)-ifnull(quantity_shipped, 0.0)+ifnull(returned_num, 0.0)) as undelivered_num")
                .eq("id", orderCustomerGoodsId).queryForMap();
        return CollectionUtils.isEmpty(orderCustomerGoods)?BigDecimal.ZERO:BigDecimalUtils.isNull(orderCustomerGoods.get("undelivered_num"));
    }
    /**----------------------------------------------------订单数量次数相关计算------end---------------------------------------------*/


    /**
     * 订单商品结束后触发修改供应商订单与客户订单状态.
     *
     * @param customerOrderIds 客户订单ID列表
     */
    public void updateStatus(List<String> customerOrderIds) {
        if (CollectionUtils.isEmpty(customerOrderIds)) {
            return;
        }
        String orderCustomerDB = getTableName(ModelConst.T_ORDER_CUSTOMER);
        String orderCustomerInSql = customerOrderIds.stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(", "));
        String orderCustomerSql = "select * from " + orderCustomerDB + " where deleted = '0' and id in (" + orderCustomerInSql + ")";
        List<Map<String, Object>> customerOrderList = jdbcTemplate.queryForList(orderCustomerSql, new HashMap<>());

        if (CollectionUtils.isEmpty(customerOrderList)) {
            return;
        }

        List<Map<String, Object>> orderGoodsList = new ArrayList<>();
        for (Map<String, Object> customerOrder : customerOrderList) {
            String orderVendorDB = getTableName(ModelConst.T_ORDER_VENDOR);
            String orderVendorSql = "select * from " + orderVendorDB + " where deleted = '0' and order_customer_id = '" + customerOrder.get("id") + "'";
            List<Map<String, Object>> vendorOrderList = jdbcTemplate.queryForList(orderVendorSql, new HashMap<>());

            if (CollectionUtils.isEmpty(vendorOrderList)) {
                throw new RuntimeException("未查到对应的供应商订单状态");
            }

            String orderCustomerGoodsDB = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
            String orderCustomerGoodsSql = "select * from " + orderCustomerGoodsDB + " where deleted = '0' and order_customer_id = '" + customerOrder.get("id") + "'";
            List<Map<String, Object>> orderCustomerGoodsList = jdbcTemplate.queryForList(orderCustomerGoodsSql, new HashMap<>());

            orderGoodsList.addAll(orderCustomerGoodsList);

            //如果为VMI订单则直接修改为已完成
            if (isVMI((String) customerOrder.get("id"))) {
                customerOrder.put("order_customer_status", CustomerOrderStatusEnum.DONE.name());

                String updateVendorStatusSql = "update " + orderVendorDB + " set status = '" + OrderVendorStatusEnum.Done.name() + "' where order_customer_id= '" + customerOrder.get("id") + "' and deleted ='0'";
                jdbcTemplate.update(updateVendorStatusSql, new HashMap<>());
                continue;
            }

            Set<OrderVendorStatusEnum> vendorOrderStatusList = new HashSet<>();
            boolean isExistNotOver = false;
            //非VMI订单需要根据订单商品状态修改供应商订单
            for (Map<String, Object> vendorOrder : vendorOrderList) {
                //如果供应商订单下的商品存在非【DONE、CLOSED、RETURNED】这三种状态则不修改
//                String orderVendorDB = getTableName(ModelConst.T_ORDER_VENDOR);
                String isExistNotOverSql = "select count (*) from " + orderVendorDB + " where deleted = '0' and id = '" + customerOrder.get("id") + "' and order_vendor_status <> 11 and order_vendor_status<> 12 and order_vendor_status <> 14 ";
                Integer existNotOver = 0;
                try {
                    existNotOver = jdbcTemplate.queryForObject(isExistNotOverSql, new HashMap<>(), Integer.class);
                } catch (DataAccessException e) {
                    e.printStackTrace();
                }

                if (existNotOver != 0) {
                    isExistNotOver = true;
                    continue;
                }

//                VendorOrderStatusEnum vendorOrderStatus = iOrderGoodsRepository.getVendorOrderStatusByOverOrderGoodsStatus(vendorOrder.getId());
//                vendorOrder.setStatus(vendorOrderStatus);

//                iVendorOrderRepository.update(vendorOrder);
//                vendorOrderStatusList.add(vendorOrderStatus);
            }

            if (isExistNotOver) {
                continue;
            }

            //根据供应商订单状态修改客户订单
            if (vendorOrderStatusList.contains(OrderVendorStatusEnum.Done.name())) {
                customerOrder.put("order_customer_status", CustomerOrderStatusEnum.DONE.name());
            } else {
                customerOrder.put("order_customer_status", CustomerOrderStatusEnum.CANCEL.name());
            }
            BoServiceUtils.updateMainBo(ModelConst.T_ORDER_CUSTOMER, customerOrder);
        }
        //修改转采订单状态
//        updateTransferOrderStatus(orderGoodsList);
    }

    /**
     * 是否为VMI订单
     *
     * @param customerOrderId
     * @return
     */
    private boolean isVMI(String customerOrderId) {
        String orderCustomerGoodsDB = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
        String orderCustomerGoodsSql = "select * from " + orderCustomerGoodsDB + " where deleted = '0' and goods_src = 'Vmi' and order_customer_id = '" + customerOrderId + "'";
        List<Map<String, Object>> orderCustomerGoodsList = jdbcTemplate.queryForList(orderCustomerGoodsSql, new HashMap<>());
        if (CollectionUtils.isEmpty(orderCustomerGoodsList)) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 批量发货
     *
     * @param orderGoodsIds 订单商品id
     * @param waybill
     * @param logistics
     * @return
     */
    public Map<String, Object> deliveryGoods(List<String> orderGoodsIds, String waybill, String logistics) {
        Map<String, Object> result = new HashMap<>();
        if (null == orderGoodsIds || orderGoodsIds.isEmpty() || null == waybill || null == logistics) {
            throw new RuntimeException("参数为空");
        }
        //批量发货
//        Long vendorOrderOrgId = iOrdersService.getVendorOrderOrgId(sessionUser.getCurrentOrgID(), orderGoodsIds.get(0));
        List<Map<String, Object>> orderVendorGoods = getOrderVendorGoodsByGoodsId(Collections.singletonList(orderGoodsIds.get(0)), null);
        SingleResponse<Department> deptRes = this.orgService.getDepartment((String) orderVendorGoods.get(0).get("vendor_organization_id"));
        //判断是否为虚拟供应商dept.getData().getExtend1() == true,即为转采采购订单
        if (deptRes.getData().getExtend1().equals("1")) {
//            List<Integer> cloudDeliverGoods = purchaseOrderService.getCloudDeliverGoods(orderGoodsIds);
//            if (!cloudDeliverGoods.isEmpty()) {
//                throw new RuntimeException("商品编号：" + cloudDeliverGoods + "，未创建转采采购订单，无法发货");
//            }
        }
        return result;
    }
}
